using System;
using System.Collections;
using System.Runtime.Remoting.Channels;

using Pegasus.Diagnostics;

namespace Pegasus.Runtime.Remoting.Channels
{
    /// <summary>
    /// Provides the implementation for the xml client formatter sink provider
    /// </summary>
    public class XmlClientFormatterSinkProvider : IClientFormatterSinkProvider
    {
        // Local Instance Values
        private IDictionary m_properties;
        private ICollection m_providerData;
        private IClientChannelSinkProvider m_next = null;

        /// <summary>
        /// Initializes a new instance of the <see cref="XmlClientFormatterSinkProvider"/> class.
        /// </summary>
        public XmlClientFormatterSinkProvider()
            : this( null, null )
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="XmlClientFormatterSinkProvider"/> class.
        /// </summary>
        /// <param name="properties">A IDictionary of configuration properties to use with the new instance of XmlClientFormatterSinkProvider.</param>
        /// <param name="providerData">A ICollection of SinkProviderData objects that contain provider data to use with the new instance of XmlClientFormatterSinkProvider.</param>
        public XmlClientFormatterSinkProvider( IDictionary properties, ICollection providerData )
        {
            // Check Parameters
            // properties can be null
            // providerData can be null

            m_properties = properties;
            m_providerData = providerData;
        }

        /// <summary>
        /// Gets or sets the next sink provider in the channel sink provider chain.
        /// </summary>
        /// <value></value>
        /// <returns>The next sink provider in the channel sink provider chain.</returns>
        /// <exception cref="T:System.Security.SecurityException">The immediate caller does not have infrastructure permission. </exception>
        /// <PermissionSet><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="Infrastructure"/></PermissionSet>
        public IClientChannelSinkProvider Next
        {
            get
            {
                return m_next;
            }

            set
            {
                m_next = value;
            }
        }

        /// <summary>
        /// Creates a sink chain.
        /// </summary>
        /// <param name="channel">Channel for which the current sink chain is being constructed.</param>
        /// <param name="url">The URL of the object to connect to. This parameter can be null if the connection is based entirely on the information contained in the remoteChannelData parameter.</param>
        /// <param name="remoteChannelData">A channel data object that describes a channel on the remote server.</param>
        /// <returns>
        /// The first sink of the newly formed channel sink chain, or null, which indicates that this provider will not or cannot provide a connection for this endpoint.
        /// </returns>
        /// <exception cref="T:System.Security.SecurityException">The immediate caller does not have infrastructure permission. </exception>
        public IClientChannelSink CreateSink( IChannelSender channel, string url, object remoteChannelData )
        {
            // Check Parameters
            ParamCode.AssertNotNull( channel, "channel" );
            ParamCode.AssertNotEmpty( url, "url" );
            // remoteChannelData can be null

            // Get the next channel skin in the chain
            IClientChannelSink nextChannelSink = null;
            if( m_next != null )
            {
                nextChannelSink = m_next.CreateSink( channel, url, remoteChannelData );
            }

            XmlClientFormatterSink xmlFormatterSink = new XmlClientFormatterSink( nextChannelSink );
            return xmlFormatterSink;
        }
    }
}
